Imports NWN2Toolset
Imports OEIShared
Imports System.Windows

Public Class rcfNWN2_Tablet
    Implements NWN2Toolset.Plugins.INWN2Plugin
    Implements VBTablet.ITablet



#Region "Controls"
    Friend WithEvents settingsControl As NWN2TabletControl.rcfNWN2TabletControl
    Friend WithEvents taskContainer As TD.SandBar.ContainerBar
    Friend WithEvents taskPanel As TD.SandBar.ContainerBarClientPanel
    Private WithEvents menu As TD.SandBar.MenuButtonItem

    'these just hold a reference to the needed controls on the Terrain Editor form
    Private raiseControl As System.Windows.Forms.RadioButton
    Private lowerControl As System.Windows.Forms.RadioButton
    Private noiseControl As System.Windows.Forms.RadioButton
    Private smoothControl As System.Windows.Forms.RadioButton
    Private flattenControl As System.Windows.Forms.RadioButton
    Private colorControl As System.Windows.Forms.RadioButton
    Private walkControl As System.Windows.Forms.RadioButton
    Private nowalkControl As System.Windows.Forms.RadioButton
    Private opTerrain As System.Windows.Forms.RadioButton
    Private opGrass As System.Windows.Forms.RadioButton
    Private opTexture As System.Windows.Forms.RadioButton
    Private paintGrass As System.Windows.Forms.RadioButton
    Private eraseGrass As System.Windows.Forms.RadioButton
    Private barPressure As System.Windows.Forms.TrackBar
    Private barOuter As System.Windows.Forms.TrackBar
    Private barInner As System.Windows.Forms.TrackBar
    Private txtInner As System.Windows.Forms.TextBox
#End Region

    Private tablet As VBTablet.Tablet
    Private bInit As Boolean = True
    Private bTabletPresent = True
    Private lastCursor As Integer

    Private TE As NWN2.Views.NWN2TerrainEditorForm


    Public ReadOnly Property DisplayName() As String Implements NWN2Toolset.Plugins.INWN2Plugin.DisplayName
        Get
            Return "NWN2Tablet"
        End Get
    End Property

    Public Sub Load(ByVal cHost As NWN2Toolset.Plugins.INWN2PluginHost) Implements NWN2Toolset.Plugins.INWN2Plugin.Load

    End Sub

    Public ReadOnly Property MenuName() As String Implements NWN2Toolset.Plugins.INWN2Plugin.MenuName
        Get
            Return "NWN2Tablet"
        End Get
    End Property

    Public ReadOnly Property Name() As String Implements NWN2Toolset.Plugins.INWN2Plugin.Name
        Get
            Return "NWN2Tablet"
        End Get
    End Property

    Public ReadOnly Property PluginMenuItem() As TD.SandBar.MenuButtonItem Implements NWN2Toolset.Plugins.INWN2Plugin.PluginMenuItem
        Get
            Return menu
        End Get
    End Property

    Public Property Preferences() As Object Implements NWN2Toolset.Plugins.INWN2Plugin.Preferences
        Get
            Return Nothing
        End Get
        Set(ByVal value As Object)

        End Set
    End Property

    Public Sub Shutdown(ByVal cHost As NWN2Toolset.Plugins.INWN2PluginHost) Implements NWN2Toolset.Plugins.INWN2Plugin.Shutdown

    End Sub

    Public Sub Startup(ByVal cHost As NWN2Toolset.Plugins.INWN2PluginHost) Implements NWN2Toolset.Plugins.INWN2Plugin.Startup
        menu = cHost.GetMenuForPlugin(Me)
        AddHandler menu.Activate, AddressOf Me.LaunchPlugin
        Try
            tablet = New VBTablet.Tablet
            tablet.UnavailableIsError = False
            tablet.hWnd = NWN2Toolset.NWN2ToolsetMainForm.App.Handle

            tablet.AddCallback(Me)

            tablet.AddContext("FirstContext")
            tablet.SelectContext("FirstContext")

            tablet.Connected = True

            tablet.Context.QueueSize = 32 'Set queue size to a reasonable value

            tablet.Context.Enabled = True
        Catch err As Exception
            'System.Windows.Forms.MessageBox.Show("An error occured trying to intialize the tablet:" + vbCrLf + err.Message)
            bTabletPresent = False
            tablet = Nothing
        End Try

    End Sub

    Public Sub Unload(ByVal cHost As NWN2Toolset.Plugins.INWN2PluginHost) Implements NWN2Toolset.Plugins.INWN2Plugin.Unload

    End Sub

    Private Sub LaunchPlugin(ByVal Sender As Object, ByVal e As EventArgs) Handles menu.Activate
        If bInit And bTabletPresent Then
            InitializeComponent()
            bInit = False
        ElseIf bTabletPresent Then
            bInit = True
        ElseIf Not bTabletPresent Then
            System.Windows.Forms.MessageBox.Show("No graphic tablet was detected during initialization." _
                + vbCrLf + "You must have a graphics tablet to use this plugin.")
        End If

        'Dim meep As frmInfo = New frmInfo
        'meep.Show()

        'Dim x As System.IO.StreamWriter = New System.IO.StreamWriter("c:\controls.txt")

        'x.WriteLine("Text/Name")
        'writeControls("", x, TE.Controls)
        'x.Flush()
        'x.Close()


    End Sub

    Private Sub writeControls(ByVal prefix As String, ByRef writer As System.IO.TextWriter, ByRef controls As System.Windows.Forms.Control.ControlCollection)
        Dim cur As System.Windows.Forms.Control

        For Each cur In controls
            writer.WriteLine(prefix + cur.Text + "/" + cur.Name)
            If cur.HasChildren Then
                writeControls(prefix + ":" + cur.Text, writer, cur.Controls)
            End If
        Next
    End Sub

    Private Function findControl(ByVal name As String, ByRef controls As System.Windows.Forms.Control.ControlCollection) As System.Windows.Forms.Control
        Dim cur, result As System.Windows.Forms.Control


        For Each cur In controls
            If cur.Name = name Then Return cur
            If cur.HasChildren Then
                result = findControl(name, cur.Controls)
                If Not result Is Nothing Then Return result
            End If
        Next

        Return Nothing
    End Function

    Private Sub InitializeComponent()

        settingsControl = New NWN2TabletControl.rcfNWN2TabletControl
        settingsControl.Location = New System.Drawing.Point(0, 0)

        taskContainer = New TD.SandBar.ContainerBar
        taskContainer.Name = "NWN2TABLET"
        taskContainer.Text = "NWN2 Tablet"
        taskPanel = New TD.SandBar.ContainerBarClientPanel
        taskPanel.Controls.Add(settingsControl)
        taskPanel.Width = 250
        taskPanel.Height = 425
        taskContainer.Controls.Add(taskPanel)
        taskContainer.Width = 300

        Dim curControl As System.Windows.Forms.Control
        For Each curControl In NWN2Toolset.NWN2ToolsetMainForm.App.Controls
            If curControl.Name = "rightSandBarDock" Then
                If Not curControl.Contains(taskContainer) Then
                    curControl.Controls.Add(taskContainer)
                    Exit For
                End If
            End If
        Next

        TE = NWN2Toolset.NWN2ToolsetMainForm.App.TerrainEditor

        raiseControl = findControl("radioButtonRaise", TE.Controls)
        colorControl = findControl("radioButtonColor", TE.Controls)
        flattenControl = findControl("radioButtonFlatten", TE.Controls)
        smoothControl = findControl("radioButtonSmooth", TE.Controls)
        noiseControl = findControl("radioButtonNoise", TE.Controls)
        walkControl = findControl("radioButtonWalk", TE.Controls)
        lowerControl = findControl("radioButtonLower", TE.Controls)
        nowalkControl = findControl("radioButtonNoWalk", TE.Controls)
        opTerrain = findControl("radioButtonElevation", TE.Controls)
        opTexture = findControl("radioButtonTexture", TE.Controls)
        opGrass = findControl("radioButtonPaintGrass", TE.Controls)
        'this is correct.  opGrass refers to the colored grass button,
        'paint and erase grass refer to the paint/erase buttons below the brush controls
        paintGrass = findControl("radioButtonGrass", TE.Controls)
        eraseGrass = findControl("radioButtonNoGrass", TE.Controls)
        barPressure = findControl("trackBarValue", TE.Controls)
        barOuter = findControl("trackBarOuterRadius", TE.Controls)
        barInner = findControl("trackBarInnerRadius", TE.Controls)
        txtInner = findControl("textBoxInnerRadius", TE.Controls)

        System.Windows.Forms.MessageBox.Show(barOuter.Maximum.ToString)

    End Sub

    Public Sub ContextClosed(ByRef Status As Integer, ByRef ContextHandle As System.IntPtr, ByRef ContextName As String) Implements VBTablet.ITablet.ContextClosed

    End Sub

    Public Sub ContextOpened(ByRef Status As Integer, ByRef ContextHandle As System.IntPtr, ByRef ContextName As String) Implements VBTablet.ITablet.ContextOpened

    End Sub

    Public Sub ContextRepositioned(ByRef OnTop As Integer, ByRef ContextHandle As System.IntPtr, ByRef ContextName As String) Implements VBTablet.ITablet.ContextRepositioned

    End Sub

    Public Sub ContextUpdated(ByRef Status As Integer, ByRef ContextHandle As System.IntPtr, ByRef ContextName As String) Implements VBTablet.ITablet.ContextUpdated

    End Sub

    Public Sub CursorChange(ByRef ContextHandle As System.IntPtr, ByRef ContextName As String) Implements VBTablet.ITablet.CursorChange

    End Sub

    Public Sub InfoChange(ByRef ManagerHandle As System.IntPtr, ByRef InfoCategory As String, ByRef InfoIndex As String) Implements VBTablet.ITablet.InfoChange

    End Sub

    Public Sub PacketArrival(ByRef ContextHandle As System.IntPtr, ByRef Cursor As Integer, ByRef X As Integer, ByRef Y As Integer, ByRef Z As Integer, ByRef Buttons As Integer, ByRef NormalPressure As Integer, ByRef TangentPressure As Integer, ByRef Azimuth As Integer, ByRef Altitude As Integer, ByRef Twist As Integer, ByRef Pitch As Integer, ByRef Roll As Integer, ByRef Yaw As Integer, ByRef PacketSerial As Integer, ByRef PacketTime As Integer) Implements VBTablet.ITablet.PacketArrival
        Dim pVal, innerVal, outerVal, pressureVal As Single

        If settingsControl Is Nothing Then
            Exit Sub
        End If

        'if the cursor has changed, we need to reset all the control values
        If Cursor <> lastCursor Or settingsControl.pens(Cursor - 1).Dirty Then
            lastCursor = Cursor
            settingsControl.SetTextureInfo()
            settingsControl.pens(Cursor - 1).Dirty = False

            If Not settingsControl.pens(Cursor - 1).BoundToSize Then
                barInner.Value = settingsControl.pens(Cursor - 1).Size
                'txtInner.Text = settingsControl.txtSize.Text
            End If
            If Not settingsControl.pens(Cursor - 1).BoundToOuter Then
                barOuter.Value = settingsControl.pens(Cursor - 1).Outer
            End If
            If Not settingsControl.pens(Cursor - 1).BoundToPressure Then
                barPressure.Value = settingsControl.pens(Cursor - 1).Pressure
            End If
        End If

        Try
            'grab the pressure from the tablet
            pVal = Math.Abs(NormalPressure)


            'set inner, or size
            If settingsControl.pens(Cursor - 1).BoundToSize Then
                innerVal = 39 / (tablet.Device.NormalPressure.Max - 1) * pVal
                If innerVal > settingsControl.pens(Cursor - 1).MaxSize Then innerVal = settingsControl.pens(Cursor - 1).MaxSize
                If innerVal < settingsControl.pens(Cursor - 1).MinSize Then innerVal = settingsControl.pens(Cursor - 1).MinSize
                barInner.Value = innerVal
            Else
                'innerVal = (39.0 / 99.0) * Single.Parse(settingsControl.txtSize.Text) + 0.61
                innerVal = settingsControl.pens(Cursor - 1).Size
            End If
            'set outer
            If settingsControl.pens(Cursor - 1).BoundToOuter Then
                outerVal = 39 / (tablet.Device.NormalPressure.Max - 1) * pVal
                If outerVal > settingsControl.pens(Cursor - 1).MaxOuter Then outerVal = settingsControl.pens(Cursor - 1).MaxOuter
                If outerVal < settingsControl.pens(Cursor - 1).MinOuter Then outerVal = settingsControl.pens(Cursor - 1).MinOuter
                barOuter.Value = outerVal
            Else
                'outerVal = (39.0 / 99.0) * Single.Parse(settingsControl.txtOuter.Text) + 0.61
                outerVal = settingsControl.pens(Cursor - 1).Outer
            End If
            'set pressure
            If settingsControl.pens(Cursor - 1).BoundToPressure Then
                pressureVal = 9999 / (tablet.Device.NormalPressure.Max - 1) * pVal
                If pressureVal > settingsControl.pens(Cursor - 1).MaxPressure Then pressureVal = settingsControl.pens(Cursor - 1).MaxPressure
                If pressureVal < settingsControl.pens(Cursor - 1).MinPressure Then pressureVal = settingsControl.pens(Cursor - 1).MinPressure
                barPressure.Value = pressureVal
            Else
                pressureVal = settingsControl.pens(Cursor - 1).Pressure
            End If
            'check for cursor id
            'set brush mode
            Select Case settingsControl.pens(Cursor - 1).Operation
                Case OEIShared.NetDisplay.TerrainModificationType.Raise
                    If Not raiseControl.Checked Then
                        raiseControl.Checked = True
                    End If
                    If Not opTerrain.Checked Then
                        opTerrain.Checked = True
                    End If
                Case OEIShared.NetDisplay.TerrainModificationType.Lower
                    If Not lowerControl.Checked Then
                        lowerControl.Checked = True
                    End If
                    If Not opTerrain.Checked Then
                        opTerrain.Checked = True
                    End If
                Case OEIShared.NetDisplay.TerrainModificationType.Flatten
                    If Not flattenControl.Checked Then
                        flattenControl.Checked = True
                    End If
                    If Not opTerrain.Checked Then
                        opTerrain.Checked = True
                    End If
                Case OEIShared.NetDisplay.TerrainModificationType.Noise
                    If Not noiseControl.Checked Then
                        noiseControl.Checked = True
                    End If
                    If Not opTerrain.Checked Then
                        opTerrain.Checked = True
                    End If
                Case OEIShared.NetDisplay.TerrainModificationType.Smooth
                    If Not smoothControl.Checked Then
                        smoothControl.Checked = True
                    End If
                Case OEIShared.NetDisplay.TerrainModificationType.Color
                    If Not colorControl.Checked Then
                        colorControl.Checked = True
                    End If
                    If Not opTerrain.Checked Then
                        opTerrain.Checked = True
                    End If
                Case OEIShared.NetDisplay.TerrainModificationType.Walk
                    If Not walkControl.Checked Then
                        walkControl.Checked = True
                    End If
                    If Not opTerrain.Checked Then
                        opTerrain.Checked = True
                    End If
                Case OEIShared.NetDisplay.TerrainModificationType.NoWalk
                    If Not nowalkControl.Checked Then
                        nowalkControl.Checked = True
                    End If
                    If Not opTerrain.Checked Then
                        opTerrain.Checked = True
                    End If
                Case OEIShared.NetDisplay.TerrainModificationType.Grass
                    If Not opGrass.Checked Then
                        opGrass.Checked = True
                    End If
                    If Not paintGrass.Checked Then
                        paintGrass.Checked = True
                    End If
                Case OEIShared.NetDisplay.TerrainModificationType.NoGrass
                    If Not opGrass.Checked Then
                        opGrass.Checked = True
                    End If
                    If Not eraseGrass.Checked Then
                        eraseGrass.Checked = True
                    End If
                Case OEIShared.NetDisplay.TerrainModificationType.Texture
                    If Not opTexture.Checked Then
                        opTexture.Checked = True
                    End If
            End Select
            'set brush
            'NWN2Toolset.NWN2ToolsetMainForm.App.TerrainEditor.SetTerrainBrush(innerVal, outerVal, pressureVal)            

        Catch err As Exception
            System.Windows.Forms.MessageBox.Show(err.Message)
        End Try

    End Sub



    Public Sub ProximityChange(ByRef InContext As Boolean, ByRef IsPhysical As Boolean, ByRef ContextHandle As System.IntPtr, ByRef ContextName As String) Implements VBTablet.ITablet.ProximityChange

    End Sub

End Class
